home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Technotools
/
Technotools (Chestnut CD-ROM)(1993).ISO
/
lang_c
/
cserial
/
vt100.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-04-04
|
22KB
|
1,223 lines
/*
* VT100.C
*
* Written for the
*
* Datalight
* Microsoft V 5.x
* TurboC
* &
* Zortech
*
* C Compilers
*
* Copyright (c) John Birchfield 1987, 1988, 1989
*/
#include <stdio.h>
#include <process.h>
#include <ctype.h>
#include "_kb.h"
#include "8250xon.h"
#include "screen.h"
#include "vt100.h"
#if (!defined (TRUE))
# define TRUE (1)
# define FALSE (0)
#endif
char Duplex [2] = { 'F', 0 },
RubOut [2] = { 255, 0 },
BackSpace [2] = { 8, 0 },
Cmask [2] = {127, 0 },
CrLf [2] = { 0, 0 };
#if (defined (STANDALONE))
#include "options.h"
void print_screen_header (void);
main (argc, argv)
int argc;
char *argv [];
{
FILE *fp;
void vt100_driver (), VT100_init ();
set_options (argc, argv);
trap_ctrl_break ();
timer_init ();
xon8250_init (Port, 4096);
fputs ("-- VT100 Terminal Emulator --\n", stdout);
if (Cfg_Str [0])
{
xon8250_port_init (Cfg_Str);
fputs (Opt_Msg, stdout);
}
else
{
xon8250_port_enable ();
fputs ("Default Port Settings Used\n", stdout);
}
fputs ("Use <Alt>F10 to exit, <Alt>F9 to spawn DOS,"
" or <Alt>F8 to Send Break\n", stdout);
screen_init();
print_screen_header ();
rowcol (23, 0);
while (xon8250_timed_read (1) != -1)
;
VT100_init ();
vt100_driver ();
xon8250_term ((Cfg_Str [0])?1:0);
timer_term ();
release_ctrl_break ();
}
void
print_screen_header ()
{
char save = Scr_ATTR;
Scr_ATTR = INVERSE;
rowcol(24,0);
cleol();
rowcol (24, 0);
aputs (INVERSE, "VT100 Emulator");
Scr_ATTR = save;
}
#endif
/*--------------------------------------------------------------------*
| All of the VT100 Specific Stuff Follows |
*--------------------------------------------------------------------*/
void ANSI_MODE (void), CUB (void), CUD (void), CUF (void),
CUP (void), CUU (void), DA (void), DECSTBM (void), DECSC (void),
DECALN (void), DECRC (void), DSR (void), ED (void), EL (void),
RESET (void), RM (void), SGR (void), SM (void), TBC (void),
escA (void), escB (void), escC (void), escD (void), escE (void),
escF (void), escG (void), escH (void), escI (void),
escJ (void), escK (void), escM (void), escY (void), escZ (void);
#define P_MAX 6 /* max no of parameter accumulators */
#define E_BUFF_MAX 11 /* max chars in escape interpreter buffer */
static int save_row, save_col,
save_attr, save_crlf,
initdone = '\0',
tab_stop[80],
special_graphics, ansi_mode,
appl_mode, DECKPNM,
vt_save_attr,
vt_save_row, vt_save_col,
vt_top, vt_bot,
vt_tlim, vt_blim,
vt_row, vt_col,
vt_crlf, vt_org,
vt_wrap, vt_xoff;
char ansi_cursor_set[] = "\\eO%c",
ansi_cursor_reset[] = "\\e[%c",
vt52_cursor[] = "\\e%c",
vt52_kp[] = "\\e?%c",
ansi_kp[] = "\\eO%c",
*kp_sptr, *cursor_sptr;
void vt_putf(char *,...),
vtpf_itoa (int),
vtput_char (char c),
VT_Put_Scr (char),
VT100_Cmd (char),
VT100_KB (char),
VT100_Out (char);
void
vt100_driver ()
{
int chin, chout;
do
{
if (!(vt_xoff) && ((chin = xon8250_read ()) != -1))
if (chin &= *Cmask)
VT100_Cmd (chin);
if ((chout = _kb ()) != -1)
{
switch (chout)
{
case PF5:
tab_stop[vt_col] = TRUE;
break;
case PF6:
tab_stop[vt_col] = FALSE;
break;
case APF8:
xon8250_write_break ();
break;
case APF9:
spawnlp (0, "COMMAND.COM", "COMMAND.COM", (char *) 0);
print_screen_header ();
vt_row = 23; vt_col = 0;
rowcol (vt_row, vt_col);
break;
case APF10:
break;
default:
if (chout != APF1)
VT100_KB (chout);
break;
}
}
} while (chout != APF10);
}
/*--------------------------- VT100_Cmd () ---------------------------*/
/*
*
*/
static int p_ix = 0, p_acc [P_MAX] = { 0 };
static char lastchar = '\0';
void
VT100_Cmd (char ch)
{
if (ch==BS)
{
if (vt_col)
{
rowcol (vt_row,--vt_col);
}
return;
}
if (lastchar && (ch==CAN || ch==SUB))
goto reset;
if (ch==DEL)
return;
switch (lastchar)
{
default:
if (ch==ESC)
{
lastchar = ch;
while (p_ix >= 0)
p_acc [p_ix--] = 0;
p_ix = 0;
return;
}
VT100_Out (ch);
return;
case ESC:
switch (ch)
{
case ESC: return;
case '[':
case '(':
case ')':
case 'Y':
case '#': lastchar = ch; return;
case '7': DECSC (); goto reset;
case '8': DECRC (); goto reset;
case '<': ANSI_MODE (); goto reset;
case '>': DECKPNM = FALSE; goto reset;
case '=': DECKPNM = TRUE; goto reset;
case 'A': escA (); goto reset;
case 'B': escB (); goto reset;
case 'C': escC (); goto reset;
case 'D': escD (); goto reset;
case 'E': escE (); goto reset;
case 'F': escF (); goto reset;
case 'G': escG (); goto reset;
case 'H': escH (); goto reset;
case 'I': escI (); goto reset;
case 'J': ED (); goto reset;
case 'K': EL (); goto reset;
case 'M': escM (); goto reset;
case 'Z': escZ (); goto reset;
case 'c': RESET (); goto reset;
case 'y': goto reset;
default : VT100_Out (ch); goto reset;
}
case '[':
switch (ch)
{
case 'A': CUU (); goto reset;
case 'B': CUD (); goto reset;
case 'C': CUF (); goto reset;
case 'D': CUB (); goto reset;
case 'H':
case 'f': CUP (); goto reset;
case 'J': ED (); goto reset;
case 'K': EL (); goto reset;
case 'c': DA (); goto reset;
case 'g': TBC (); goto reset;
case 'h': SM (); goto reset;
case 'l': RM (); goto reset;
case 'm': SGR (); goto reset;
case 'n': DSR (); goto reset;
case 'q': goto reset;
case 'r': DECSTBM (); goto reset;
case ';': p_ix++;
case '?': return;
default:
if isdigit (ch)
{
p_acc [p_ix] *= 10;
p_acc [p_ix] += (ch-'0');
return;
}
VT100_Out (ch);
goto reset;
}
case '(':
case ')': goto reset;
case '#':
if (ch=='8')
DECALN ();
goto reset;
case 'Y':
p_acc [p_ix++] = ch - 31;
if (p_ix < 2)
break;
else
{
CUP ();
goto reset;
}
}
return;
reset:
lastchar = '\0';
}
/*--------------------------- VT100_Out () ---------------------------*/
/*
*
*/
void
VT100_Out (char ch)
{
switch (ch)
{
case BEL:
putchar (ch);
rowcol (vt_row, vt_col);
break;
case HT:
while (vt_col < 79)
if (tab_stop[++vt_col])
break;
rowcol(vt_row, vt_col);
break;
case DEL:
case ESC:
break;
default:
VT_Put_Scr (ch);
break;
}
}
/*------------------------- VT_Put_Scr () -------------------------*/
/*
*
*/
void
VT_Put_Scr (char ch)
{
static char vt_wrapped = FALSE;
if (vt_wrapped)
{
if (ch == CR)
return;
vt_wrapped = FALSE;
if (ch == LF)
return;
}
if (vt_row > vt_bot)
{
rowcol (vt_row=vt_bot, vt_col);
scroll_up (1, vt_top, 0, vt_bot, 79);
}
switch (ch)
{
case CR:
vt_col = 0;
rowcol (vt_row, vt_col);
if (vt_crlf == FALSE)
break;
case LF:
case VT:
case FF:
if (++vt_row > vt_bot)
scroll_up (1, vt_top, 0, vt_row=vt_bot, 79);
rowcol (vt_row, vt_col);
break;
default:
aput (Scr_ATTR, ch);
if (++vt_col > 79)
{
if (!vt_wrap)
rowcol (vt_row, --vt_col);
else
{
vt_col = 0;
vt_row++;
vt_wrapped = TRUE;
}
}
break;
}
}
/*---------------------------- DECALN () ----------------------------*/
/*
*
*/
void
DECALN (void)
{
int i=1920;
rowcol (0, 0);
while (i--)
aput (Scr_ATTR, 'E');
rowcol (vt_row, vt_col);
}
/*----------------------------- DECSC () -----------------------------*/
/*
* ESC 7 - Save Cursor (DEC Private)
*/
void
DECSC (void)
{
vt_save_row = vt_row;
vt_save_col = vt_col;
vt_save_attr = Scr_ATTR;
}
/*----------------------------- DECRC () -----------------------------*/
/*
* ESC 8 - Restore Cursor (DEC Private)
*/
void
DECRC (void)
{
vt_row = vt_save_row;
vt_col = vt_save_col;
Scr_ATTR = vt_save_attr;
rowcol (vt_row, vt_col);
}
/*------------------------------ DSR () ------------------------------*/
/*
*
*/
void
DSR (void)
{
switch (p_acc [0])
{
case 5: vt_putf ("\\e[0n"); break;
case 6: vt_putf ("\\e[%d;%dR", vt_row + 1, vt_col + 1); break;
default: break;
}
}
/*--------------------------- ANSI_MODE () ---------------------------*/
/*
* ESC < - Enter ANSI Mode
*/
void
ANSI_MODE (void)
{
ansi_mode = TRUE;
kp_sptr = ansi_kp;
cursor_sptr = (appl_mode)? ansi_cursor_set: ansi_cursor_reset;
}
/*------------------------------ SGR () ------------------------------*/
/*
*
*/
void
SGR (void)
{
char blink = FALSE,
bold = FALSE,
underscore = FALSE,
reverse = FALSE;
int i;
for (i = 0; i < P_MAX; i++)
switch (p_acc[i])
{
case 1:
bold = TRUE;
break;
case 4:
underscore = TRUE;
break;
case 5:
blink = TRUE;
break;
case 7:
reverse = TRUE;
break;
default:
break;
}
if (underscore)
{
Scr_ATTR = UNDERLINE;
if (reverse)
Scr_ATTR |= INVERSE;
}
else if (reverse)
Scr_ATTR = INVERSE;
else
Scr_ATTR = NORMAL;
if (bold)
Scr_ATTR |= BRIGHT;
if (blink)
Scr_ATTR |= BLINK;
}
/*----------------------------- escA () -----------------------------*/
/*
*
*/
void
escA (void)
{
if ((ansi_mode == FALSE) && (vt_row))
rowcol (--vt_row, vt_col);
}
/*----------------------------- escB () -----------------------------*/
/*
*
*/
void
escB (void)
{
if ((ansi_mode == FALSE) && (vt_row < 23))
rowcol (++vt_row, vt_col);
}
/*----------------------------- escC () -----------------------------*/
/*
*
*/
void
escC (void)
{
if ((ansi_mode == FALSE) && (vt_col < 79))
rowcol (vt_row, ++vt_col);
}
/*----------------------------- escD () -----------------------------*/
/*
*
*/
void
escD (void)
{
if (ansi_mode)
if (vt_row < vt_bot)
rowcol (++vt_row, vt_col);
else
scroll_up (1, vt_top, 0, vt_bot, 79);
else if (vt_col)
rowcol (vt_row, --vt_col);
}
/*----------------------------- escE () -----------------------------*/
/*
*
*/
void
escE (void)
{
if (ansi_mode)
{
vt_col = 0;
if (vt_row < vt_bot)
rowcol (++vt_row, vt_col);
else
{
scroll_up (1, vt_top, 0, vt_bot, 79);
rowcol (vt_row, vt_col);
}
}
}
/*----------------------------- escF () -----------------------------*/
/*
*
*/
void
escF (void)
{
special_graphics = TRUE;
}
/*----------------------------- escG () -----------------------------*/
/*
*
*/
void
escG (void)
{
special_graphics = FALSE;
}
/*----------------------------- escH () -----------------------------*/
/*
*
*/
void
escH (void)
{
if (ansi_mode)
{
tab_stop [vt_col] = TRUE;
return;
}
vt_row = vt_col = 0;
rowcol (vt_row, vt_col);
}
/*----------------------------- escI () -----------------------------*/
/*
*
*/
void
escI (void)
{
if (ansi_mode == FALSE)
if (vt_row > vt_top)
rowcol (--vt_row, vt_col);
else
{
scroll_dn (1, vt_top, 0, vt_bot, 79);
rowcol (vt_row, vt_col);
}
}
/*----------------------------- escJ () -----------------------------*/
/*
*
*/
void
escJ (void)
{
if (ansi_mode == FALSE)
{
clrscrn ();
rowcol (vt_row, vt_col);
}
}
/*----------------------------- escK () -----------------------------*/
/*
*
*/
void
escK (void)
{
if (ansi_mode == FALSE)
scroll_up (0, vt_row, vt_col, vt_row, 79);
}
/*----------------------------- escM () -----------------------------*/
/*
*
*/
void
escM (void)
{
if (ansi_mode)
if (vt_row > vt_top)
rowcol (--vt_row, vt_col);
else
{
scroll_dn (1, vt_top, 0, vt_bot, 79);
rowcol (vt_row, vt_col);
}
}
/*----------------------------- escZ () -----------------------------*/
/*
*
*/
void
escZ (void)
{
vt_putf ("\\e/Z");
}
/*------------------------------ DA () ------------------------------*/
/*
*
*/
void
DA (void)
{
vt_putf ("\\e[?1;0c");
}
/*------------------------------ CUU () ------------------------------*/
/*
* ESC [ Pn A - Cursor Up
*/
void
CUU (void)
{
do
{
if (vt_row > vt_tlim)
rowcol (--vt_row, vt_col);
} while (--p_acc[0] > 0);
}
/*------------------------------ CUD () ------------------------------*/
/*
* ESC [ Pn B - Cursor Down
*/
void
CUD (void)
{
do
{
if (vt_row < vt_blim)
rowcol (++vt_row, vt_col);
} while (--p_acc[0] > 0);
}
/*------------------------------ CUF () ------------------------------*/
/*
* ESC [ Pn C - Cursor Forward
*/
void
CUF (void)
{
do
{
if (vt_col < 79)
rowcol (vt_row, ++vt_col);
} while (--p_acc[0] > 0);
}
/*------------------------------ CUB () ------------------------------*/
/*
* ESC [ Pn D - Cursor Backward
*/
void
CUB (void)
{
do
{
if (vt_col)
rowcol (vt_row, --vt_col);
} while (--p_acc[0] > 0);
}
/*------------------------------ CUP () ------------------------------*/
/*
* ESC [ Pn ; Pn H - Cursor Position
* or
* ESC [ Pn ; Pn f - Horizontal and Vertical Position
*/
void
CUP (void)
{
if (p_acc[0])
--p_acc[0];
if (p_acc[1])
--p_acc[1];
vt_row = p_acc[0] + vt_tlim; vt_col = p_acc[1];
vt_row = (vt_row<24)?vt_row:23;
vt_col = (vt_col<80)?vt_col:79;
if (vt_row <= vt_blim)
rowcol (vt_row, vt_col);
}
/*------------------------------ ED () ------------------------------*/
/*
* ESC [ Ps J - Erase in Display
*/
void
ED (void)
{
int ch;
if (vt_row < vt_top || vt_row > vt_bot)
return;
switch (p_acc[0])
{
case 0: /* from current cursor position to end of page */
scroll_up (0, vt_row, vt_col, vt_row, 79);
if (vt_row < vt_bot)
scroll_up (0, vt_row+1, 0, vt_bot, 79);
break;
case 1: /* from start of screen to current position */
if (vt_row > vt_top)
scroll_up (0, vt_top, 0, vt_row-1, 79);
scroll_up (0, vt_row, 0, vt_row, vt_col);
break;
case 2:
scroll_up (0, vt_top, 0, vt_bot, 79);
break;
default:
break;
}
}
/*------------------------------ EL () ------------------------------*/
/*
* ESC [ Ps K - Erase In Line
*/
void
EL (void)
{
int ch;
if (vt_row < vt_top || vt_row > vt_bot)
return;
switch (p_acc[0])
{
case 0:
scroll_up (0, vt_row, vt_col, vt_row, 79);
break;
case 1: /* from start of line to current position */
scroll_up (0, vt_row, 0, vt_row, vt_col);
break;
case 2:
scroll_up (0, vt_row, 0, vt_row, 79);
break;
default:
break;
}
}
/*------------------------------ TBC () ------------------------------*/
/*
* ESC [ Ps g - Tabulation Clear
*/
void
TBC (void)
{
int i;
if (p_acc[0] == 0)
tab_stop [vt_col] = FALSE;
else if (p_acc[0] == 3)
for (i = 0; i < 80; i++)
tab_stop [i] = FALSE;
}
/*------------------------------ SM () ------------------------------*/
/*
* ESC [ Ps ; ... ; Ps h - Set Mode
*/
void
SM (void)
{
int i;
for (i = 0; i < P_MAX; i++)
switch (p_acc[i])
{
case 1:
appl_mode = TRUE;
cursor_sptr = ansi_cursor_set;
break;
case 5:
Scr_ATTR = INVERSE;
break;
case 6:
vt_org = TRUE;
vt_tlim = vt_row = vt_top;
vt_blim = vt_bot;
vt_col = 0;
rowcol (vt_row, vt_col);
break;
case 7:
vt_wrap = TRUE;
break;
case 20:
vt_crlf = TRUE;
break;
}
}
/*-------------------------- RM () --------------------------*/
/*
* ESC [ Ps l - Reset Mode
*/
void
RM (void)
{
int i;
for (i = 0; i < P_MAX; i++)
switch (p_acc[i])
{
case 1:
appl_mode = FALSE;
cursor_sptr = ansi_cursor_reset;
break;
case 2:
ansi_mode = FALSE;
cursor_sptr = vt52_cursor;
kp_sptr = vt52_kp;
break;
case 5:
Scr_ATTR = NORMAL;
break;
case 6:
vt_org = FALSE;
vt_row = vt_tlim = 0; vt_col = 0;
vt_blim = 23;
rowcol (vt_row, vt_col);
break;
case 7:
vt_wrap = FALSE;
break;
case 20:
vt_crlf = FALSE;
break;
}
}
/*---------------------------- DECSTBM () ----------------------------*/
/*
*
*/
void
DECSTBM (void)
{
if (p_acc [0]) p_acc [0]--;
if (p_acc [1]) p_acc [1]--;
if (p_acc[1] > p_acc[0])
{
vt_top = p_acc[0];
vt_bot = (p_acc[1] < 24) ? p_acc [1]: 23;
vt_tlim = (vt_org) ? vt_top: 0;
vt_blim = (vt_org) ? vt_bot: 23;
vt_row = vt_tlim; vt_col = 0;
rowcol (vt_row, vt_col);
}
}
/*----------------------------- RESET () -----------------------------*/
/*
*
*/
void
RESET (void)
{
int i;
appl_mode = DECKPNM = FALSE;
ansi_mode = vt_wrap = TRUE;
cursor_sptr = ansi_cursor_reset;
kp_sptr = ansi_kp;
vt_tlim = vt_top = 0;
vt_blim = vt_bot = 23;
vt_crlf = (*CrLf == 'Y')? 1: 0;
vt_xoff = vt_org = FALSE;
p_ix = 0;
for (i = 0; i < 80; i++)
tab_stop[i] = '\0';
i = g_rowcol ();
vt_row = i / 256; vt_col = i % 256;
lastchar = '\0';
}
/*-------------------------- VT100_init () --------------------------*/
/*
*
*/
void
VT100_init ()
{
int i;
if (initdone == FALSE)
{
appl_mode = DECKPNM = FALSE;
ansi_mode = vt_wrap = TRUE;
cursor_sptr = ansi_cursor_reset;
kp_sptr = ansi_kp;
vt_tlim = vt_top = 0;
vt_blim = vt_bot = 23;
vt_crlf = (*CrLf == 'Y')? 1: 0;
vt_xoff = vt_org = FALSE;
p_ix = 0;
for (i = 0; i < 80; i++)
tab_stop[i] = '\0';
i = g_rowcol ();
vt_row = i / 256; vt_col = i % 256;
lastchar = '\0';
initdone = TRUE;
}
for (i = 0; i < P_MAX; i++)
p_acc[i] = 0;
p_ix = 0;
rowcol (vt_row, vt_col);
}
/*--------------------------- VT100_KB () ---------------------------*/
/*
*
*/
void
VT100_KB (char ch)
{
if ((ch >= PF1) && (ch <= PF4))
vt_putf (kp_sptr, ('P' + ch - PF1));
else if ((ch >= SPF1) && (ch <= SPF10))
if (ch == SPF10)
if (DECKPNM)
vt_putf (kp_sptr, 'p');
else
vtput_char ('0');
else if (DECKPNM)
vt_putf (kp_sptr, ('q' + ch - SPF1));
else
vtput_char (ch - SPF1 + '1');
else if ((ch >= UPCHAR) && (ch <= LFCHAR))
vt_putf (cursor_sptr, (ch - UPCHAR + 'A'));
else
switch (ch)
{
case PF7:
if (DECKPNM)
vt_putf (kp_sptr, 'm');
else
vtput_char ('-');
break;
case PF8:
if (DECKPNM)
vt_putf (kp_sptr, 'l');
else
vtput_char (',');
break;
case PF9:
if (DECKPNM)
vt_putf (kp_sptr, 'n');
else
vtput_char ('.');
break;
case PF10:
if (DECKPNM)
vt_putf (kp_sptr, 'M');
else
vtput_char (CR);
break;
case HCHAR:
vt_putf (cursor_sptr, 'H');
break;
case DEL1:
vtput_char (*RubOut);
break;
case BS:
vtput_char (*BackSpace);
break;
default:
vtput_char (ch);
break;
}
}
void vt_putf(cp, cv)
char *cp; int cv;
{
char c;
int *cvp,i;
cvp = &cv;
while(*cp)
switch(c = *cp++)
{
case '\\':
vtput_char((c = *cp++) == 'e' ? ESC : c);
break;
case '%':
switch (c = *cp++)
{
case 'c':
vtput_char (*cvp++);
break;
case 'n':
c = *cp++;
while (!xon8250_write_buffer_empty ())
;
for (i = 1000 * (c - '0'); i > 0; i--)
;
break;
case 'd':
vtpf_itoa (*cvp++);
break;
default:
break;
}
break;
default:
vtput_char(c);
break;
}
}
void
vtput_char (char c)
{
int i;
if (*Duplex == 'H')
VT100_Cmd (c);
while (xon8250_write (c) == -1)
;
if (c==XOFF)
vt_xoff = TRUE;
else if (c==XON)
vt_xoff = FALSE;
}
static char vtpf_str [6];
void vtpf_itoa (int i)
{
char *cp;
cp = vtpf_str;
*cp = '\0';
i = (i < 0) ? -i: i;
while (i)
{
*cp++ = (i % 10) + '0';
i /= 10;
}
while (--cp >= vtpf_str)
{
if (*Duplex == 'H')
VT100_Cmd (*cp);
while (xon8250_write (*cp) == -1)
;
}
}
void
vt_scrup (int cnt, int tr, int tc, int br, int bc)
{
char sv_atr;
sv_atr = Scr_ATTR;
if (Scr_ATTR != 0x70 && Scr_ATTR != 0x79)
Scr_ATTR = NORMAL;
scroll_up (cnt, tr, tc, br, bc);
Scr_ATTR = sv_atr;
}